package com.ccb.afm.util;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.logging.Logger;
import java.util.zip.GZIPInputStream;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.SystemUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import net.sf.cindy.Buffer;
import net.sf.cindy.buffer.BufferBuilder;

import com.ccb.BytePackage;
import cn.tworen.demou.remoting.AmfMessage;
import cn.tworen.demou.remoting.Body;
import cn.tworen.demou.remoting.HexDump;
import cn.tworen.demou.remoting.amf.AmfDecode;
import cn.tworen.demou.remoting.amf.AmfEncode;

public class CodingFactory {
	public final static Charset utf8 = Charset.forName("utf-8");
	public final static Charset gb2312 = Charset.forName("gb2312");
	private static Log log = LogFactory.getLog(CodingFactory.class);
	/**
	 * 将字节流以一个易于观察的方式打成字符串
	 * 
	 * @param bytes
	 *            字节流
	 * @param charset
	 *            字节的编码
	 * @return 字节流的一个易于观察的表现形式
	 */
	public static String PrintHex(byte[] bytes, Charset charset) {
		if (bytes == null)
			bytes = new byte[0];

		StringBuffer buffer = new StringBuffer("ADDR |  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F |  D A T A [" + bytes.length + "]" + SystemUtils.LINE_SEPARATOR);

		int lineCount = bytes.length % 16 == 0 ? bytes.length / 16 : bytes.length / 16 + 1;
		for (int i = 0; i < lineCount; i++) {
			int count = i == lineCount - 1 ? bytes.length % 16 == 0 ? 16 : bytes.length % 16 : 16;

			String addr = StringUtils.leftPad(Integer.toHexString(i).toUpperCase(), 3, '0') + "0";
			StringBuffer body = new StringBuffer(48);
			String data = new String(bytes, 16 * i, count, charset);

			for (int j = 0; j < count; j++) {
				byte b = bytes[i * 16 + j];

				// 15 = 00001111(2)
				int m = b >> 4 & 15;
				int n = b & 15;

				body.append(" ");
				body.append((char) (m > 9 ? 'A' + m - 10 : '0' + m));
				body.append((char) (n > 9 ? 'A' + n - 10 : '0' + n));
			}

			StringBuffer dataBuffer = new StringBuffer();
			for (int j = 0; j < data.length(); j++)
				dataBuffer.append(data.charAt(j) < 32 ? '.' : data.charAt(j));

			buffer.append(addr).append(" |");
			buffer.append(StringUtils.rightPad(body.toString(), 48)).append(" | ");
			buffer.append(dataBuffer.toString()).append(SystemUtils.LINE_SEPARATOR);
		}

		return buffer.toString();
	}
	public static byte[] readFile(String filename) throws IOException{  
		BufferedInputStream bufferedInputStream=new BufferedInputStream(new FileInputStream(filename));  
		int len=bufferedInputStream.available();  
		byte[] bytes=new byte[len];  
		int r=bufferedInputStream.read(bytes);  
		if(len!=r)  
		{  
		  bytes=null;  
		  throw new IOException("读取文件不正确");  
		}  
		bufferedInputStream.close();  
		return bytes;  
	}  
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		CodingFactory cf=new CodingFactory();
		AmfEncode afe=new AmfEncode();
		Buffer bb=afe.encode(cf.getmaterials("32e48ec1478fa9960d4409c03fc90b60"));
		System.out.println(bb.dump());
		

	}
	
	
	public byte[] getInputStream(String sess,String filename) throws IOException
	{
		
	/*	AmfEncode afe=new AmfEncode();
		Buffer bb=afe.encode(getmaterials(sess));
	    //ByteBufferInputStream bbis=new ByteBufferInputStream(bb.asByteBuffer());
		 System.out.println(bb.dump());
	    byte []temp=new byte[bb.limit()];
	    for(int i=0;i<temp.length;i++)
	    {
	    	temp[i]=bb.get(i);
	    }
	  */
		
		byte []temp=readFile(filename);
		log.debug(PrintHex(temp, this.utf8));
		BytePackage bp=new BytePackage();
		bp.Append(temp);
		bp.Replace(59, sess.getBytes());
		log.debug(PrintHex(bp.getbytes(), this.utf8));
		return bp.getbytes();
	}
	
	
	public byte[] getInputStream(String sess,String filename,int start)throws IOException
	{
		byte []temp=readFile(filename);
		log.debug(PrintHex(temp, this.utf8));
		BytePackage bp=new BytePackage();
		bp.Append(temp);
		bp.Replace(start, sess.getBytes());
		log.debug(PrintHex(bp.getbytes(), this.utf8));
		return bp.getbytes();
	}
	
    public AmfMessage getmaterials(String sess)
    {
    	AmfMessage afm=new AmfMessage();
    	afm.setVersion(3);
    	Body body=new Body();
    	body.setTargetURI("/3");
    	body.setResponseURI("houseking:shop.getmaterials");
    	
    	Object []midS={"mid",219038};
    	Object []sessstr={"sess",sess};
    	Object []bodyObjects={midS,sessstr};
    	body.setValue(bodyObjects);
    	
    	afm.addBody(body);
    	
    	return afm;
    	
    }
	
	public static AmfMessage decodezipmsg(InputStream is)
	{
		 BufferBuilder bb=new BufferBuilder();
		  GZIPInputStream gzin;
		try {
			gzin = new GZIPInputStream(is);
	
		  byte[] buf = new byte[20000];  
		  BytePackage  bp=new BytePackage();
		  
		          int len;  
		          while ((len = gzin.read(buf)) > 0) {  
		              bp.Append(buf, len);
		          }  
		          gzin.close(); 
	      bb.append(bp.getbytes());
	      log.debug(bb.toBuffer().dump());
	      AmfDecode amfDecode=new AmfDecode();
		  AmfMessage message=amfDecode.decode(bb.toBuffer());
		  return message;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
		return null;
	}
	
	public static float getFvalue(String name,HashMap body)
	{
		System.out.println(body.get(name));
	    return Float.parseFloat(""+body.get(name));
	
		
	}
	
	public static int getIvalue(String name,HashMap body)
	{
	
	return (Integer)body.get(name);
		
	}
	
	

}
